﻿#region Copyright RenGuiYou. All rights reserved.

//=====================================================
// NeatlyFrameWork
// Author:      RenGuiyou
// Feedback: 	mailto:750539605@qq.com
//=====================================================

#endregion

using System;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using UnityEngine.UI;

namespace Neatly.UI
{
    [ExecuteInEditMode]
    [DisallowMultipleComponent]
    public class NCheckBox : NUIBehaviour, IPointerClickHandler, IPointerDownHandler, IPointerUpHandler
    {
        protected enum SelectionState
        {
            Normal,
            Pressed,
            Disabled
        }

        [SerializeField]
        protected bool m_IsCheck = false;
        [SerializeField]
        public Graphic m_ImgCross;

        [SerializeField]
        protected bool m_Interactable = true;
        protected SelectionState m_CurrentSelectionState;

        private Action m_OnClick;
        private Action m_OnPointerDown;
        private Action m_OnPointerUp;

        protected override void Awake()
        {
            m_ImgCross?.SetActive(m_IsCheck);
        }

        public void SetCheck(bool val)
        {
            if (m_ImgCross == null)
            {
                NDebug.LogError("Check box Image is null.");
                return;
            }
            if (m_IsCheck==val)
            {
                return;
            }
            m_IsCheck = val;
            m_ImgCross.SetActive(m_IsCheck);
        }

        public bool GetCheck()
        {
            return m_IsCheck;
        }

        protected override void OnEnable()
        {
            base.OnEnable();
            m_CurrentSelectionState = SelectionState.Normal;
            OnSetProperty();
        }

        protected bool IsInteractable()
        {
            return m_Interactable;
        }

        protected void OnSetProperty()
        {
            if (IsInteractable())
            {
                if (m_CurrentSelectionState == SelectionState.Disabled)
                {
                    m_CurrentSelectionState = SelectionState.Normal;
                }
            }
            else
            {
                m_CurrentSelectionState = SelectionState.Disabled;
            }
        }

        public void SetInteractable(bool value)
        {
            if (SetPropertyUtility.SetStruct(ref m_Interactable, value))
            {
                OnSetProperty();
            }
        }

        public void OnPointerDown(PointerEventData eventData)
        {
            if (!IsActive() || !IsInteractable())
                return;
            m_CurrentSelectionState = SelectionState.Pressed;
            OnSetProperty();
            if (m_OnPointerDown != null)
            {
                m_OnPointerDown.Invoke();
            }
        }

        public void OnPointerUp(PointerEventData eventData)
        {
            if (!IsActive() || !IsInteractable())
                return;
            m_CurrentSelectionState = SelectionState.Normal;
            OnSetProperty();
            if (m_OnPointerUp!=null)
            {
                m_OnPointerUp.Invoke();
            }
        }
        
        public void OnPointerClick(PointerEventData eventData)
        {
            if (!IsActive() || !IsInteractable())
                return;
            SetCheck(!m_IsCheck);
            if(m_OnClick != null)
                m_OnClick.Invoke();
        }

        public void AddClickListener(Action action)
        {
            m_OnClick = action;
        }
        
        public void AddPointerDownListener(Action action)
        {
            m_OnPointerDown = action;
        }

        public void AddPointerUpListener(Action action)
        {
            m_OnPointerUp = action;
        }
    }
}